package com.ibm.ops.domain.report;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.StringReader;

import org.apache.log4j.Logger;

import com.ibm.ops.OpstoolConstant;
import com.ibm.ops.domain.OpsLogMetaDataType;
import com.ibm.ops.domain.metadata.OpsAuditLogInfosourceReportMetaData;
import com.ibm.ops.domain.metadata.OpsAuditLogReportMetaData;

public class OpsAuditLogInfosourceReport extends OpsAuditLogReport {
	
	private static final Logger logger = Logger.getLogger(OpsAuditLogInfosourceReport.class);

	private static final String SPECIAL_EXCEPTION_CODE = "OT0006E";
	
	private static final String SPECIAL_EXCEPTION_CONTENT 
		= "Internal InfoSource error within a certain function.. InfoSource error with return code : com.ibm.infosource.exceptions.GeneralInfosourceException: Order does not exist in the database -- OrderInfo";
	
	@Override
	protected OpsAuditLogReportMetaData constructOpsAuditLogReportMetaData(String metaData) {	
		return this.retrieveInfosourceMetaData(metaData);
	}

	@Override
	protected OpsAuditLogReportMetaDataKey retrieveOpsAuditLogReportMetaDataKey(String metaData) {
		String key = null;
		if(this.currentMetaData != null){
			if(this.currentMetaData instanceof OpsAuditLogInfosourceReportMetaData){
				OpsAuditLogInfosourceReportMetaData obj = ((OpsAuditLogInfosourceReportMetaData) this.currentMetaData);
				key = this.getKey(obj);		
			}			
		}else{
			OpsAuditLogInfosourceReportMetaData infosourceMetaData = this.retrieveInfosourceMetaData(metaData);
			key = this.getKey(infosourceMetaData);
		}
		return new OpsAuditLogReportMetaDataKey(key);
	}

	private String getKey(OpsAuditLogInfosourceReportMetaData data){
		String key = "";
		String exceptionCode = data.getException_code();
		String exceptionContent = data.getException_content();
		if(SPECIAL_EXCEPTION_CODE.equalsIgnoreCase(exceptionCode)){
			if(SPECIAL_EXCEPTION_CONTENT.equalsIgnoreCase(exceptionContent) == false){
				key = data.getMo_num().substring(0, 2) + data.getModule() + data.getException_code() + data.getException_content();
			}else{
				key = data.getModule() + data.getException_code() + data.getException_content();
			}
		}else{
			key = data.getModule() + data.getException_code() + data.getException_content();
		}
		return key;
	}
	
	private OpsAuditLogInfosourceReportMetaData retrieveInfosourceMetaData(String metaData){
		OpsAuditLogInfosourceReportMetaData infosourceMetaData = new OpsAuditLogInfosourceReportMetaData();
		infosourceMetaData.setType(OpsLogMetaDataType.INFOSOURCE);
		//first line
		BufferedReader br = null;
		String formerMo = "Init";
		br = new LineNumberReader(new StringReader(metaData));
		String line = "";
		int  count = 0;
		try {
			while((line = br.readLine()) != null){
				if(line.length() > 0){
					if(count == 1){
						String[] members = line.split(OpstoolConstant.INFOSOURCE_REPORT_META_DATA_FIRST_LINE_SPLIT_TAG);
//						System.out.println(members[0]);
						if(members[0].split(OpstoolConstant.INFOSOURCE_REPORT_META_DATA_FIRST_LINE_ElEMENT_SPLIT_TAG).length < 2){
							formerMo = null;
							infosourceMetaData.setMo_num(formerMo);
							infosourceMetaData.setModule(members[3].split(OpstoolConstant.INFOSOURCE_REPORT_META_DATA_FIRST_LINE_ElEMENT_SPLIT_TAG)[1].trim());
							infosourceMetaData.setTimestamp(members[4].split(OpstoolConstant.INFOSOURCE_REPORT_META_DATA_FIRST_LINE_ElEMENT_SPLIT_TAG)[1].trim());
						}else{
							formerMo = members[0].split(OpstoolConstant.INFOSOURCE_REPORT_META_DATA_FIRST_LINE_ElEMENT_SPLIT_TAG)[1].trim();
							infosourceMetaData.setMo_num(formerMo);
							infosourceMetaData.setModule(members[1].split(OpstoolConstant.INFOSOURCE_REPORT_META_DATA_FIRST_LINE_ElEMENT_SPLIT_TAG)[1].trim());
							infosourceMetaData.setTimestamp(members[2].split(OpstoolConstant.INFOSOURCE_REPORT_META_DATA_FIRST_LINE_ElEMENT_SPLIT_TAG)[1].trim());
						}
					}else if(count == 2){
						int index = line.indexOf(":");
						String exceptionCode = line.substring(0,index).trim();
						String exceptionContent = line.substring(index + 1).trim();
						infosourceMetaData.setException_code(exceptionCode);
						infosourceMetaData.setException_content(exceptionContent);
					}					
				}
				count++;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (RuntimeException e){
			logger.warn("can not parse infosource meta data : " + line + ". due to " + e.getMessage());
		}
		this.currentMetaData = infosourceMetaData;
		return infosourceMetaData;
	}
}
